// Copyright (C) 2002-2006 Aaron Griffith
// For conditions of distribution and use, see copyright notice in irrlicht.h

#ifndef __C_PLY_MESH_FILE_LOADER_H_INCLUDED__
#define __C_PLY_MESH_FILE_LOADER_H_INCLUDED__

#include "IMeshLoader.h"
#include "IMeshManipulator.h"
#include "irrString.h"
#include "irrArray.h"
#include "ILogger.h"
#include "SMeshBuffer.h"

namespace irr
{
	namespace scene
	{

		//! Meshloader capable of loading ply meshes.
		class CPLYMeshFileLoader : public IMeshLoader
		{
		public:
			//! Constructor
			CPLYMeshFileLoader(IMeshManipulator* meshm, ILogger* logm);

			//! destructor
			virtual ~CPLYMeshFileLoader();

			//! returns true if the file maybe is able to be loaded by this class
			//! based on the file extension (e.g. ".cob")
			virtual bool isALoadableFileExtension(const c8* fileName);

			//! creates/loads an animated mesh from the file.
			//! \return Pointer to the created mesh. Returns 0 if loading failed.
			//! If you no longer need the mesh, you should call IAnimatedMesh::drop().
			//! See IUnknown::drop() for more information.
			virtual IAnimatedMesh* createMesh(irr::io::IReadFile* file);

		private:
			struct SPlyMeshPropertyDescription
			{
				core::stringc name;
				core::stringc type;
			};
			struct SPlyMeshElementDescription
			{
				core::stringc name;
				u32 count;
				core::array<struct SPlyMeshPropertyDescription> properties;
			};
			struct SPlyMeshValue
			{
				core::stringc name;
				bool isAList;
				f64 v;
				core::array<f64> list;
			};

			core::array<struct SPlyMeshElementDescription> elements;

			IMeshManipulator* mm;
			ILogger* log;
			SMeshBuffer* meshbuffer;

			core::array<core::stringc> splitLines(core::stringc st);
			core::array<core::stringc> splitSpaces(core::stringc st);

			void handleVertex(core::array<struct SPlyMeshValue> values);
			void handleFace(core::array<struct SPlyMeshValue> values);

			bool parseHeader(core::array<core::stringc> lines);
			bool parseData(core::array<core::stringc> lines);
			bool parseElement(u32 i, core::array<core::stringc> lines);

			f64 atod(core::stringc s);

			void error(core::stringc s, bool warn = false);
		};

	} // end namespace scene
} // end namespace irr

#endif
